<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>轮播图demo</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <style>
        .carousel {
            max-width: 800px;
            display: flex;
            position: relative;
            overflow: hidden;
        }

        .carousel .control {
            position: absolute;
            width: 100%;
            height: 100%;
        }

        .carousel .control .next, .carousel .control .prev {
            position: absolute;
            top: calc(50% - 2rem);
            cursor: pointer;
            user-select: none;
            background: rgba(66, 66, 66, .66);
            border-radius: 50%;
            padding: 6px 8px 4px;
        }

        .carousel .control .next {
            right: 1rem;
        }

        .carousel .control .prev {
            left: 1rem;
        }

        .carousel img {
            width: 100%;
            display: flex;
            justify-content: flex-start;
            /* 切换动画 改变transform时触发 0.5秒内完成 */
            transition: transform .5s ease;
        }

        .carousel .control .indicators {
            position: absolute;
            right: 0;
            bottom: 2rem;
            left: 0;
            z-index: 2;
            display: flex;
            justify-content: center;
        }

        .carousel .control .indicators .indicator {
            flex: 0 1 auto;
            width: 30px;
            height: 3px;
            margin-right: 3px;
            margin-left: 3px;
            cursor: pointer;
            background-color: #fff;
            background-clip: padding-box;
            opacity: .5;
            border-top: 1rem solid transparent;
            border-bottom: 1rem solid transparent;
            transition: opacity .5s ease;
        }
    </style>
</head>
<body>
<!--
    class="carousel" 为必填项
    autoplay="true"  为选填项 开启自动播放
    timeout="1000"   为选填项 开启自动播放间隔时间 默认5000
-->
<div class="carousel" autoplay="true" timeout="3000">
    <img src="img/1.webp">
    <img src="img/2.webp">
    <img src="img/3.webp">
    <img src="img/4.webp">
    <img src="img/5.webp">
</div>

<script>
    const init = function () {
        const carousel = document.querySelector('.carousel');
        const size = carousel.querySelectorAll('img').length;
        const autoplay = carousel.getAttribute("autoplay") === "true";
        const timeout = carousel.getAttribute("timeout") ? Number(carousel.getAttribute("timeout")) : 5000;
        const auto = function () {
            carousel.setAttribute('index', String(Number(carousel.getAttribute('index')) >= size - 1 ? 0 : Number(carousel.getAttribute('index')) + 1));
        };
        // 每5秒自动切换下一张
        let interval = autoplay ? window.setInterval(auto, timeout) : null;
        const observer = new MutationObserver(function (mutations) {
            mutations.forEach(e => {
                // 改为监听 attribute 的方案统一处理变化
                if (e.target.className == 'carousel') {
                    const index = e.target.getAttribute('index');
                    document.querySelectorAll('.carousel img').forEach(img => {
                        img.style.transform = 'translateX(' + (index * -100) + '%)';
                    });
                    document.querySelectorAll('.indicator').forEach((indicator, i) => {
                        indicator.style.opacity = (i === Number(index) ? "1" : "0.5");
                    });
                    // 数值发生变化自动重新计算 避免闪屏
                    if(autoplay){
                        clearInterval(interval);
                        interval = window.setInterval(auto, timeout);
                    }
                }
            });
        });
        observer.observe(carousel, {attributes: true});
        // 用js添加控制器模块dom 减少html中代码
        const control = document.createElement('div');
        control.className = 'control';
        const prev = document.createElement('div');
        prev.className = 'prev';
        prev.innerHTML = '<svg t="1690880358537" viewBox="0 0 1024 1024" p-id="2638" width="24" height="24"><path style="fill: whitesmoke;" d="M659.748571 245.272381l-51.687619-51.687619-318.439619 318.585905 318.415238 318.268952 51.712-51.736381-266.703238-266.556952z" p-id="2639"></path></svg>';
        const next = document.createElement('div');
        next.className = 'next';
        next.innerHTML = '<svg t="1690880498698" viewBox="0 0 1024 1024" p-id="2777" width="24" height="24"><path style="fill: whitesmoke;" d="M605.086476 512.146286L338.358857 245.272381l51.760762-51.687619 318.415238 318.585905L390.095238 830.415238l-51.687619-51.736381z" p-id="2778"></path></svg>';
        prev.addEventListener('click', function () {
            carousel.setAttribute('index', String(Number(carousel.getAttribute('index')) < 1 ? size - 1 : Number(carousel.getAttribute('index')) - 1));
        });
        next.addEventListener('click', function () {
            carousel.setAttribute('index', String(Number(carousel.getAttribute('index')) >= size - 1 ? 0 : Number(carousel.getAttribute('index')) + 1));
        });
        const indicators = document.createElement('div');
        indicators.className = 'indicators';
        for (let i = 0; i < size; i++) {
            const indicator = document.createElement('div');
            indicator.className = 'indicator';
            indicator.addEventListener('click', function () {
                carousel.setAttribute('index', String(i));
            });
            indicators.appendChild(indicator);
        }
        control.appendChild(prev);
        control.appendChild(next);
        control.appendChild(indicators);
        carousel.appendChild(control);
        // 初始化index
        carousel.setAttribute('index', '0');
    }
    window.onload = init;
</script>
</body>
</html>
